package com.bidevalution.business.impl;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.bidevalution.business.common.RedisKeys;
import com.bidevalution.business.dto.WebSocketSendTimeKeyDto;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.bidevalution.support.context.ChannelContext;
import com.bidevalution.support.context.RedisKeyConstants;
import com.bidevalution.support.context.RequestObject;
import com.bidevalution.support.context.ResponseObject;
import com.bidevalution.support.context.WebSocketOpTypeEnum;
import com.bidevalution.support.factory.WebSocketService;
import com.bidevalution.support.websocket.WebSocketCached;
import com.google.common.collect.Lists;
import com.qtp.core.redis.RedisUtil;
import com.qtp.core.util.GsonUtil;

import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

@Service
public class WebSocketServiceImpl implements WebSocketService {
	private Logger logger = Logger.getLogger(getClass());

	@Override
	public void receive(ChannelContext channelContext, RequestObject requestObject) {
		logger.info("用户注册:"+requestObject.getAccessToken()+"请求类型:"+requestObject.getOpType()+",数量:"+WebSocketCached.dataMap.size());
		if (WebSocketOpTypeEnum.EXPERT_REGISTER.name().equals(requestObject.getOpType())) {
			String expertId = RedisUtil.get(RedisKeyConstants.webSoketToken + requestObject.getAccessToken());
			if (StringUtils.isEmpty(expertId)) {
				channelContext.getChannelHandlerContext().writeAndFlush(
						new TextWebSocketFrame(GsonUtil.toJson(new ResponseObject(WebSocketOpTypeEnum.EXPERT_REGISTER)
								.error("accessToken:" + requestObject.getAccessToken() + ":非法访问"))));
				return;
			}
			logger.info(""+WebSocketCached.getExpertChannelContextMap().size());
			WebSocketCached.dataMap.put(channelContext.getChannelHandlerContext().channel().id().asLongText(), channelContext);
			WebSocketCached.getExpertChannelContextMap().put(expertId, channelContext);
			send(channelContext, new ResponseObject(WebSocketOpTypeEnum.EXPERT_REGISTER).success("用户注册成功"));
		} else if (WebSocketOpTypeEnum.ANSWER.name().equals(requestObject.getOpType())) {
			send(channelContext, new ResponseObject(WebSocketOpTypeEnum.ANSWER).success("定时发送信息成功"));
		} else if (WebSocketOpTypeEnum.CLIENT_RESPONSE.name().equals(requestObject.getOpType())) {
			RedisUtil.delKeysInMap(RedisKeys.WebSocketSendTime.name(), requestObject.getReceiveKey());
			send(channelContext, new ResponseObject(WebSocketOpTypeEnum.RECEIVE_CLIENT).success("收到客户端反馈"));
		}
	}

	@Override
	public void send(ChannelContext channelContext, ResponseObject responseObject) {
		try {
			String sectionId = channelContext.getAccessToken();
			logger.info(sectionId+"发送消息:"+responseObject);
			// 需要前端反馈列表
			if (responseObject.getTodoList() != null) {
				RedisUtil.getAllMap(RedisKeys.WebSocketSendTime.name());
				String key = RedisKeys.WebSocketSendTime.name();
				int expireSecond = RedisKeys.WebSocketSendTime.expireSecond;
				Long timestamp = System.currentTimeMillis();
				for (String[] values: responseObject.getTodoList()) {
					String md5 = values[0];
					String chandId = values[1];
					String hashKey = WebSocketSendTimeKeyDto.getKey(chandId, responseObject.getOpType(), md5);
					responseObject.setMd5(md5);

					responseObject.setReceiveKey(hashKey);
					responseObject.setTimestamp(timestamp);
					String value = GsonUtil.toJson(responseObject);
					RedisUtil.addValueToMap(key, hashKey, value);
				}
				RedisUtil.expire(key, expireSecond);
			}

			channelContext.sendMessage(responseObject);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}

	}
	/**
	 * 清除内存中保存在channel对象
	 * <p>Description: </p>
	 * @param channelId
	 * @see com.bidevalution.support.factory.WebSocketService remove(com.bidevalution.support.context.ChannelContext)
	 */
	@Override
	public void remove(String channelId) {
		List<String> removeIds = Lists.newArrayList();
		for (Entry<String, ChannelContext> entry : WebSocketCached.getExpertChannelContextMap().entrySet()) {
			if (entry.getValue().getChannelHandlerContext().channel().id().toString()
					.equals(channelId)) {
				removeIds.add(entry.getKey());
			}
		}
		for(String removeId:removeIds) {
			WebSocketCached.getExpertChannelContextMap().remove(removeId);
		}
	}

	@Override
	public ChannelContext getChannelContext(String channelId) {
		for (Entry<String, ChannelContext> entry : WebSocketCached.getExpertChannelContextMap().entrySet()) {
			if (entry.getValue().getChannelHandlerContext().channel().id().toString()
					.equals(channelId)) {
				return entry.getValue();
			}
		}
		return null;
	}

}
